// $URL: http://mingw-lib.googlecode.com/svn/trunk/local/box/yt_new/widget.cpp $
// $Rev: 790 $
// $Author: akio.miyoshi $
// $Date:: 2012-10-19 10:38:40 +0000#$

#include "widget.h"
#include "ui_widget.h"
#include <QtCore>
#include <QtGui>
#include <QtNetwork>
#include <QtSql>
#include <QtXml>
#include <QtWebKit>
#include <QtUiTools>

#include "webview.h"
#include "xmlutil.h"
#include "yt_web.h"
#include "env.h"
#include "t_youtube_dump_lib.h"

// http://gihyo.jp/dev/feature/01/qt/0006?page=5

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

	//m_sort_type = "delta";
	//m_sort_type = "unit_delta";
	bool v_conn_status = connect(
			&m_video_list, SIGNAL(sig_sort_spec(QString)),
			this, SLOT(slot_sort_spec(QString)));
    qDebug() << "[v_conn_status]" << v_conn_status ;

	webView_2 = new WebView(ui->groupBox_2);
	webView_2->setObjectName(QString::fromUtf8("webView_2"));
	webView_2->setUrl(QUrl("about:blank"));
	ui->horizontalLayout_2->addWidget(webView_2);

    //QWidget::setWindowFlags(Qt::WindowStaysOnTopHint); // top most

    QString localSysName = QLocale::system().name();

    QTranslator *translator = new QTranslator(this);
    translator->load(QLatin1String("qt_") + localSysName, ":/translations");
    QApplication::installTranslator(translator);

    QTranslator *translator2 = new QTranslator(this);
    translator2->load(QLatin1String("yt_dump_") + localSysName, ":/translations");
    QApplication::installTranslator(translator2);


    ////nam = new NetworkAccessManager();
    nam = g_Env->nam;

    qDebug() << "[nam]" << (uint)nam;
    qDebug() << "[QThread::currentThread()]" << QThread::currentThread();
    QByteArray v_test = nam->doGet("box://a/b?c=d");
    qDebug() << "[v_test]" << v_test;

    yt = new YtManager(nam);

	webView_2->page()->setNetworkAccessManager(nam);

	ytweb = new YtWeb(webView_2);

	connect(webView_2->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
            this, SLOT(populateJavaScriptWindowObject2()));
    //int v_webView_width = 400;
#if 0x0
    int v_webView_width = 200;
    ui->webView->setMinimumWidth(v_webView_width);
    ui->webView->setMaximumWidth(v_webView_width);
#endif

	webView_2->setContextMenuPolicy(Qt::NoContextMenu);

	webView_2->setUrl(QUrl("qrc:/page/page2.html"));

    //DB Open
    m_db = T_Youtube_Dump_Lib::getDumpDatabase();
    if (!m_db.open())
    {
		qDebug() << "ng";
		qDebug() << m_db.lastError();
		qApp->quit();
		//qApp->exit(0);
        return;
    }
    else
    {
        qDebug() << "ok";
    }

    connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));

    ////nam->addToSilentList(QRegExp("[.]jpg$"));

    //nam->addToSilentList("http:");
#if 0x0
	nam->addToSilentList("file:");
    nam->addToSilentList("qrc:");
    nam->addToSilentList("http://i.ytimg.com/vi/");
    nam->addToSilentList("http://video-stats.video.google.com/");
    nam->addToSilentList("http://s2.youtube.com/");
    nam->addToSilentList("http://i1.ytimg.com/vi/");
    nam->addToSilentList("http://i2.ytimg.com/vi/");
    nam->addToSilentList("http://i3.ytimg.com/vi/");
    nam->addToSilentList("http://i4.ytimg.com/vi/");
    nam->addToSilentList("http://googleads.g.doubleclick.net/pagead/");
    nam->addToSilentList("http://pagead2.googlesyndication.com/pagead/");
    nam->addToSilentList("http://googleads.g.doubleclick.net/");
    nam->addToSilentList("http://www.youtube.com/player_");
    nam->addToSilentList("http://www.youtube.com/set_awesome?");
	nam->addToSilentList("http://s.ytimg.com/");
	nam->addToSilentList(new QRegExp("(/crossdomain.xml)$"));
	nam->addToSilentList("http://www.youtube.com/embed_api_rest?");
	//nam->addToSilentList("http://www.youtube.com/v/");
	nam->addToSilentList("http://www.youtube.com/get_video?");
	nam->addToSilentList("http://www.youtube.com/get_video_info?");
#endif

	ui->groupBox->setMaximumWidth(100);
#if 0x0
	//webView_2->setMaximumWidth(400);
	//ui->groupBox_2->setMinimumWidth(500);
	m_mplayerwindow->setMinimumWidth(800);
	m_mplayerwindow->resize(500, 300);
#endif

#if 0x0
    ui->widget->resize(300, 200);
    m_mplayerwindow->resize(300, 200);
#endif

	QDesktopServices::setUrlHandler(QLatin1String("http"), this, "openUrl");

	ui->label->setText(g_Env->youtube_auth_key);

	QDesktopWidget *v_desktop = QApplication::desktop();
	this->setMaximumWidth(v_desktop->width() - 20);
    //resize(1000, 500);
}

void Widget::openUrl(const QUrl &url)
{
	qDebug() << "[Widget::openUrl()]" << url;
}

Widget::~Widget()
{
    delete ui;
}

void Widget::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void Widget::populateJavaScriptWindowObject1()
{
}

void Widget::populateJavaScriptWindowObject2()
{
	webView_2->page()->mainFrame()->addToJavaScriptWindowObject("web1", this);
	webView_2->page()->mainFrame()->addToJavaScriptWindowObject("list1", &this->m_video_list);
	webView_2->page()->mainFrame()->addToJavaScriptWindowObject("page1", g_Env->page1);
}

void Widget::requestFinished(QNetworkReply *reply)
{
	QString v_url = reply->url().toString();
	if(!v_url.endsWith(".jpg"))
	{
		g_Env->showMessage(v_url);
	}
#if 0x0 // xxx
    if(v_url.startsWith("http://o-o.preferred."))
    {
        qDebug() << "[REQUEST]";
        qDebug() << "reply->operation()" << reply->operation();
        foreach(QByteArray v_first, reply->request().rawHeaderList())
        {
            qDebug() << v_first << reply->request().rawHeader(v_first);
        }
        qDebug() << "[REPLY]";
        qDebug() << "RedirectionTargetAttribute" << reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
        qDebug() << "HttpStatusCodeAttribute" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        qDebug() << "HttpReasonPhraseAttribute" << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute);
        qDebug() << "RedirectionTargetAttribute" << reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
        qDebug() << "ContentTypeHeader" << reply->header(QNetworkRequest::ContentTypeHeader);
        qDebug() << "ContentLengthHeader" << reply->header(QNetworkRequest::ContentLengthHeader);
        qDebug() << "LocationHeader" << reply->header(QNetworkRequest::LocationHeader);
        foreach(QByteArray v_first, reply->rawHeaderList())
        {
            qDebug() << v_first << reply->rawHeader(v_first);
        }
    }
#endif
    //if(nam->isInSilentList(reply->url())) return;
    //qDebug() << "[Widget::requestFinished]" << reply->url();
}

void Widget::setDesktopFile(QFile &file, QString name)
{
    QString dirPath =
            QDesktopServices::storageLocation(
                    QDesktopServices::DesktopLocation);
    QDir dir(dirPath);
    QString filePath = dir.filePath(name);
    file.setFileName(filePath);
}

void Widget::saveDesktopFile(QString name, QByteArray bytes)
{
    QFile file;
    setDesktopFile(file, name);
    qDebug() << file.fileName();
    file.open(QIODevice::WriteOnly | QIODevice::Truncate);
    file.write(bytes);
}

void Widget::cmd_refresh_display()
{
	QApplication::processEvents(QEventLoop::AllEvents);
#if 0x0
	this->webView_2->hide();
	this->webView_2->show();
	this->webView_2->update();
#endif
}

void Widget::cmd_reload_web()
{
	QString v_tbl_name = m_video_list.get_tbl_name();
	QDateTime v_time_1 = QDateTime::currentDateTime();
	T_VideoList v_total;
	v_total.clear();
	if(m_video_list.m_domain.startsWith("fv:"))
	{
		QString v_user = m_video_list.m_domain;
		v_user.replace("fv:", "");
		yt->listUsersFavoriteWeb(v_user, &v_total);
	}
	else if(m_video_list.m_domain.startsWith("pl:"))
	{
		QString v_plist_id = m_video_list.m_domain;
		v_plist_id.replace("pl:", "");
		yt->listPlaylistVideoWeb(v_plist_id, &v_total);
	}
	QDateTime v_time_2 = QDateTime::currentDateTime();
	qDebug() << "[v_total.size()]" << v_total.size();

	if(v_total.size() == 0)
	{
		qDebug() << "(v_total.size() == 0)";
		return;
	}

	qDebug() << "[QSqlDriver::Transactions]" << m_db.driver()->hasFeature(QSqlDriver::Transactions);
	bool v_ok = m_db.transaction();
	qDebug() << "[v_ok]" << v_ok;
	QSqlQuery query;
	query.exec(QString("delete from %1").arg(v_tbl_name));
	qDebug() << "[deleted]";

	v_total.sort_internal("total");
	for(int i=0; i<v_total.size(); i++)
	{
		T_Video *v_rec = v_total.value(i);
		v_rec->page = ((v_rec->pos - 1) / 20) + 1;
		v_rec->view_rank = i + 1;
		yt->dbVideoInsert(v_rec, v_tbl_name);
		if(!yt->dbVideoExists(v_rec->id, (v_tbl_name+"_old")))
		{
			qDebug() << "[insert(old)]" << v_rec;
			yt->dbVideoInsert(v_rec, (v_tbl_name+"_old"));
		}
	}
	qDebug() << "[inserted]";
	m_db.commit();
	this->ui->pushButton->setEnabled(true);
	qDebug() << "[DIFF]" << (v_time_2.toTime_t() - v_time_1.toTime_t());
	QString v_diff_msg = QString("[DIFF] %1 sec").arg(v_time_2.toTime_t() - v_time_1.toTime_t());
	this->ui->label->setText(v_diff_msg);
	cmd_reload_db();
}

void Widget::cmd_reload_db()
{
	QString v_tbl_name = m_video_list.get_tbl_name();

	//this->ui->webView->setHtml("");
	//this->webView_2->setHtml("");

	QWebElement v_mydiv;
	ytweb->initPage(this->webView_2, &v_mydiv);

	yt->dbVideoListLoad(&m_video_list, v_tbl_name, m_video_list.m_keyword);
	m_video_list.sort(m_video_list.m_sort_type);
}

void Widget::on_pushButton_clicked()
{
	//webView_2->setUrl(QUrl("qrc:/page/page1.html"));
	webView_2->setUrl(QUrl("http://www.youtube.com/user/HarunoMegami#p/a/u/1/g7_5PBr1i4A"));
}

void Widget::on_pushButton_2_clicked()
{
	webView_2->setUrl(QUrl("http://www.youtube.com/watch?v=g7_5PBr1i4A"));
	//QString v_str = "abc&xyz";
	//qDebug() << Qt::escape(v_str);
#if 0x1
    QApplication::setOverrideCursor(Qt::WaitCursor);
    this->ui->pushButton_2->setEnabled(false);
    {
		this->ui->label->setText("on_pushButton_2_clicked()");
		cmd_reload_db();
	}
    this->ui->pushButton_2->setEnabled(true);
    QApplication::restoreOverrideCursor();
#endif
}

void Widget::on_pushButton_3_clicked()
{
	this->slotEditFind();
	return;
}

void Widget::on_pushButton_4_clicked()
{
	qDebug() << "on_pushButton_4_clicked()";

/*
{RecPlaylist:
 <guid> "http://gdata.youtube.com/feeds/api/users/akmiyoshi/playlists/C04C0F9A39F92146"
 <id> "C04C0F9A39F92146"
 <title> "最強の萌えキャラ"
 <published> QDateTime("木 7 2 03:34:25 2009")
}
http://gdata.youtube.com/feeds/api/playlists/C04C0F9A39F92146
http://www.youtube.com/my_playlists?p=C04C0F9A39F92146&pi=0
 */
}

void Widget::on_pushButton_5_clicked()
{
    qDebug() << "on_pushButton_5_clicked()";
}

void Widget::openWithBrowser(QString a_url)
{
    QString v_cmd = QString("start %1").arg(a_url);
    v_cmd.replace("&", "^&");
    system(v_cmd.toLatin1().constData());
}

void Widget::dbgmsg(QString a_msg)
{
    qDebug() << "[dbgmsg()]" << a_msg;
	g_Env->showMessage(a_msg);
}

void Widget::submitFavoritePage(int a_page)
{
	qDebug() << "submitFavoritePage()" << a_page;
	QString v_page_url;
	if(m_video_list.m_domain.startsWith("pl:"))
	{
		QString v_plist_id = m_video_list.m_domain;
		v_plist_id.replace("pl:", "");
		v_page_url = QString("http://www.youtube.com/my_playlists?p=%1&pi=%2")
					 .arg(v_plist_id).arg(a_page-1);
	}
	else if(m_video_list.m_domain.startsWith("fv:"))
	{
		v_page_url = QString("http://www.youtube.com/my_favorites?pi=%1")
					 .arg(a_page-1);
	}
	if(v_page_url.isEmpty()) return;
    openWithBrowser(v_page_url);
}

void Widget::submitFavoritePage2(int a_page, QString a_id)
{
	qDebug() << "submitFavoritePage()" << a_page;
	QString v_page_url;
	if(m_video_list.m_domain.startsWith("pl:"))
	{
		QString v_plist_id = m_video_list.m_domain;
		v_plist_id.replace("pl:", "");
		v_page_url = QString("http://www.youtube.com/my_playlists?p=%1&pi=%2")
					 .arg(v_plist_id).arg(a_page-1);
	}
	else if(m_video_list.m_domain.startsWith("fv:"))
	{
        //int v_start_index = ((a_page - 1) * 20) + 1;
        a_page = (a_page-1)*20/100;
        v_page_url = QString("http://www.youtube.com/my_favorites?pi=%1")
                     //.arg(a_page-1);
                     .arg(a_page);
    }
    if(v_page_url.isEmpty()) return;
	openWithBrowser(v_page_url);
}


void Widget::submitIdToReset(QString a_id)
{
	qDebug() << "submitIdToReset()" << a_id;
	QString v_tbl_name = m_video_list.get_tbl_name();
	T_Video *v_rec = m_video_list.select(a_id);
	if(!v_rec) return;
	T_Video v_rec_old;
	if(yt->dbVideoSelect(a_id, v_tbl_name+"_old", &v_rec_old))
	{
#if 0x0
        if(v_rec->view_count == v_rec_old.view_count)
        {
            //v_rec->view_ts = v_rec_old.view_ts;       //avoid overwriting old value
            v_rec->view_count = v_rec->view_count_old; //avoid overwriting old value
        }
#endif
        ////qDebug() << v_rec;
		////qDebug() << "submitIdToReset(before delete)" << a_id;
		yt->dbVideoDelete(a_id, v_tbl_name+"_old");
	}
	////qDebug() << "submitIdToReset(before insert)" << a_id;
	yt->dbVideoInsert(v_rec, v_tbl_name+"_old");
}

int Widget::submitIdToRaise(QString a_id)
{
	qDebug() << "submitIdToRaise()" << a_id;
    int v_status = 0;
    v_status = submitIdToDelete(a_id, true);
    qDebug() << v_status;
    if(v_status != 200) return 1;

	QString v_xml =
			QString(
			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
			"<entry xmlns=\"http://www.w3.org/2005/Atom\">"
			"<id>%1</id>"
			"</entry>"
			).arg(a_id);
			;

	//qDebug() << v_xml;

	QByteArray v_post_xml = v_xml.toLatin1();
    QUrl v_post_url("http://gdata.youtube.com/feeds/api/users/akmiyoshi/favorites");
    //QUrl v_post_url("http://gdata.youtube.com/feeds/api/users/default/favorites");
    QNetworkRequest v_post_request;
	v_post_request.setUrl(v_post_url);
	v_post_request.setRawHeader("Authorization", QString("GoogleLogin auth=%1").arg(g_Env->youtube_auth_key).toLatin1().constData());
	v_post_request.setRawHeader("X-GData-Key", QString("key=%1").arg(g_Env->youtube_devl_key).toLatin1().constData());
	v_post_request.setRawHeader("Content-Type", "application/atom+xml");

	QByteArray v_result;
    /*int*/ v_status = nam->batPost(v_post_request, v_post_xml, v_result);
	qDebug() << v_result;
	qDebug() << v_status;
	if(v_status != 201) return 2;

	return 0;
}

int Widget::submitIdToDelete(QString a_id, bool a_keep_in_db)
{
	qDebug() << "submitIdToDelete()" << a_id;

    QNetworkRequest v_request;

    //bool YtManager::dbVideoSelect(QString a_id, QString a_tbl_name, T_Video *a_rec)
    QString v_tbl_name = m_video_list.get_tbl_name();
    T_Video *v_rec = m_video_list.select(a_id);
    if(!v_rec) return -404;

    QUrl v_url(v_rec->self);
    v_request.setUrl(v_url);
    v_request.setRawHeader("GData-Version", "1");
    //v_request.setRawHeader("Authorization", QString("Bearer %1").arg(g_Env->youtube_auth_key).toLatin1().constData());
    v_request.setRawHeader("Authorization", QString("GoogleLogin auth=%1").arg(g_Env->youtube_auth_key).toLatin1().constData());
    v_request.setRawHeader("X-GData-Key", QString("key=%1").arg(g_Env->youtube_devl_key).toLatin1().constData());
    int v_status = nam->batDelete(v_request);
    qDebug() << "[Widget::submitIdToDelete()]: v_status" << v_status;

	if(v_status != 200) return v_status;

    if(!a_keep_in_db)
    {
        m_video_list.deleteById(a_id);
        QString v_tbl_name = m_video_list.get_tbl_name();
        yt->dbVideoDelete(a_id, v_tbl_name);
    }

	return v_status;
}

void Widget::submitIdToBrowse(QString a_id)
{
    qDebug() << "submitIdToBrowse()" << a_id;
    QString v_page_url = QString("http://www.youtube.com/watch?v=%1")
                        .arg(a_id);
    openWithBrowser(v_page_url);
}

void Widget::submitIdToPlay(QString a_id)
{
    qDebug() << "submitIdToPlay()" << a_id;
#if 0x1
    QWebElement v_mydiv;
	ytweb->initPage(this->webView_2, &v_mydiv);
	ytweb->pageVideoPlay(&v_mydiv, a_id, 0);
#endif
}

void Widget::submitIdToPlay2(QString a_id)
{
    QFile v_program;
    v_program.setFileName(QString("C:\\Program Files\\SMPlayer\\smplayer.exe"));
    QString v_url = QString("http://www.youtube.com/watch?v=%1").arg(a_id);
    QStringList v_arguments;
    v_arguments << v_url;
    QProcess::startDetached(v_program.fileName(), v_arguments);
}

void Widget::submitIdToRelated(QString a_id)
{
    qDebug() << "submitIdToRelated()" << a_id;
    QApplication::setOverrideCursor(Qt::WaitCursor);
    {
        QWebElement v_mydiv;
		ytweb->initPage(this->webView_2, &v_mydiv);

        QString v_url_str = QString("http://gdata.youtube.com/feeds/api/videos/%1/related")
                            .arg(a_id);
        //openWithBrowser(v_url_str);
        QUrl v_url;
        v_url.setUrl(v_url_str);
        BatchNetworkAccessManager v_bnam;
        //QByteArray v_xml = NetworkThreadRequest::doGet2(v_url);
        QByteArray v_xml = v_bnam.doGet(v_url);
        XmlUtil::backupXmlBody(v_xml, "pageVideoPlay");

		T_VideoList v_result;
		yt->parseXmlForEntryList(v_xml, &v_result);
        qDebug() << v_result.size();

        ytweb->pageVideoPlay(&v_mydiv, a_id, &v_result);
    }
    QApplication::restoreOverrideCursor();
}


void Widget::submitIdToDownload(QString a_id)
{
    //xxx
    //QMessageBox::information(0, "debug", QString("[Widget::submitIdToDownload(%1)]").arg(a_id));
    QFile v_program;
    T_Youtube_Dump_Lib::getDownloadExe(v_program);
    qDebug() << "getDownloadExe()" << v_program.fileName() ;
    v_program.fileName();
    QStringList v_arguments;
    v_arguments << a_id;
    QProcess::startDetached(v_program.fileName(), v_arguments);
}

void Widget::submitStreamToPlay(QString a_target)
{
	qDebug() << "submitStreamToPlay()" << a_target;
}

void Widget::slotEditFind()
{
	bool ok;
	QString search = QInputDialog::getText(this, tr("Find"),
										  tr("Text:"), QLineEdit::Normal,
										  m_lastSearch, &ok);
	if (ok && !search.isEmpty()) {
		m_lastSearch = search;
		if (!webView_2->findText(m_lastSearch))
		{
			//slotUpdateStatusbar(tr("\"%1\" not found.").arg(m_lastSearch));
		}
	}
	qDebug() << "[Widget::slotEditFind(end)]" << m_lastSearch;
}

void Widget::slotEditFindNext()
{
	qDebug() << "[Widget::slotEditFindNext(1)]" << m_lastSearch;
	if (m_lastSearch.isEmpty()) return;
	qDebug() << "[Widget::slotEditFindNext(1)]";
	webView_2->findText(m_lastSearch);
	qDebug() << "[Widget::slotEditFindNext(3)]";
}

void Widget::slotEditFindPrevious()
{
	if (m_lastSearch.isEmpty()) return;
	webView_2->findText(m_lastSearch, QWebPage::FindBackward);
}

void Widget::slot_sort_spec(QString a_type)
{
	qDebug() << "Widget::slot_sort_spec(QString a_type)" << a_type;
	m_video_list.m_sort_type = a_type;
}
